﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using Xman.WebApi.Filters.Model;

namespace Xman.WebApi.Filters;

public class ApiResultFilterAttribute : ActionFilterAttribute
{
    /// <summary>
    /// ContentResult	表示带有文本内容的响应，并允许指定内容类型。
    /// EmptyResult 表示不返回任何结果的动作方法。
    /// FileResult 作为抽象类，提供下载文件的功能（包括 FileContentResult, FileStreamResult, 和 PhysicalFileResult 等具体实现）
    /// JsonResult 返回 JSON 格式的数据。从 ASP.NET Core 6 开始，推荐使用 ControllerBase.Json 方法代替直接使用 JsonResult。
    /// ObjectResult 可以包含任何类型的对象，并使用内容协商来确定响应格式。
    /// PhysicalFileResult 表示返回物理文件路径的文件结果。
    /// RedirectResult 执行到指定 URL 的重定向。
    /// RedirectToActionResult 执行到指定控制器动作的重定向。
    /// RedirectToRouteResult 执行基于指定路由的重定向。
    /// StatusCodeResult 表示只有状态码的响应。
    /// UnauthorizedResult 表示请求未授权的响应，通常对应 HTTP 401 状态码。
    /// </summary>
    /// <param name="context"></param>
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        var noWarp = actionDescriptor?.MethodInfo.GetCustomAttributes(inherit: true).Any(a => a.GetType() == typeof(NoWrapAttribute)) == true;

        if (context.Result is ValidationResult)
        {
            //参数校验不通过的
            var objectResult = context.Result as ValidationResult;
            context.Result = new OkObjectResult(new ResultWrapper(StatusCodes.Status400BadRequest, objectResult?.Value.ToString()));
        }
        else if (context.Result is ObjectResult objectResult && !noWarp)
        {
            //正常非标记NoWarp的
            context.Result = new OkObjectResult(new ResultWrapper(result: objectResult?.Value));
        }
        else if (context.Result is EmptyResult emptyResult && !noWarp)
        {
            //正常非标记NoWarp的
            context.Result = new OkObjectResult(new ResultWrapper());
        }
        else
        {
            //非ObjectResult直接输出
        }
    }
}